
/**
 * @file msg_com.h
 * @author your name (you@domain.com)
 * @brief pub and sub communication mode
 * @version 0.1
 * @date 2023-05-28
 * 
 * @copyright Copyright (c) 2023
 * 
 */

#ifndef MSG_COM_H
#define MSG_COM_H

#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "log.h"

#ifdef __cplusplus
extern "C"
{
#endif

#define  MSG_CENTER_LOG(fmt, ...)  COMLOG_DEBUG_LOG(fmt, ##__VA_ARGS__)

#define  ANY_ID (0xFFFFFFFF)

typedef  void(*HandleEvent)(char *event_name, void *data, int data_len, int srcId);
typedef  void(*MutexLock)(bool lock);

/* 订阅事件节点 */
typedef struct EventSubscriberNode
{
    char  event[32];
    HandleEvent func;
	int needId;
    struct EventSubscriberNode *next;
}EventSubscriberNode_t;


/* 发布事件节点 */ 
typedef struct EventPublishNode
{
    char  event[32]; 
    void  *data; //内部会拷贝一份，并自动释放
	int   srcId;
    struct EventPublishNode *next;
}EventPublishNode_t;

typedef struct MsgCenterHandle
{
	MutexLock       mutexSubscriber;
    MutexLock       mutexPublish;
	EventSubscriberNode_t *eventSubscriberHead;
	EventPublishNode_t    *eventPublishHead;
	volatile int                   exit_flg;
}MsgCenterHandle_t;

/**
 * @brief init msg center
 * 
 * @param mutexSubscriber mutex lock func
 * @param mutexPublish    mutex lock func
 * @return MsgCenterHandle_t* handle
 */
MsgCenterHandle_t *MsgCenterInit(MutexLock mutexSubscriber, MutexLock mutexPublish);

/**
 * @brief deinit handle and set it null
 * 
 * @param msg_handle MsgCenterHandle_t **
 */
void MsgCenterDeinit(MsgCenterHandle_t **msg_handle);

/**
 * @brief loop call this func, 
 * the shorter the interval, the faster the event execution
 * @param msg_handle MsgCenterHandle_t *
 * @return int -1 error 0 success
 */
int MsgCenterLoop(MsgCenterHandle_t *msg_handle);

/**
 * @brief Subscriber one event
 * 
 * @param handle 
 * @param event event topic name
 * @param func 
 * @param needId only listen the event with the needId(Event sender ID),
 *        ANY_ID not judged needId(Event sender ID)
 * @return int  -1 error 0 success
 */
int SubscriberEvent(MsgCenterHandle_t *handle, char *event, HandleEvent func, int needId);

/**
 * @brief cancel listen one event
 * 
 * @param handle 
 * @param event 
 * @param func 
 * @return int  -1 error 0 success
 */
int ReleaseSubscriberEvent(MsgCenterHandle_t *handle, char *event, HandleEvent func);

/**
 * @brief publish one event
 * 
 * @param handle 
 * @param event event topic name
 * @param data 
 * @param datalen 
 * @param srcId Event sender ID
 * @return int -1 error 0 success
 */
int PublishEvent(MsgCenterHandle_t *handle, char *event, void *data, int datalen, int srcId);

#ifdef __cplusplus
}
#endif


#endif